package com.mrd.frame.onlinepay.pay.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.demo.trade.config.Configs;
import com.alipay.demo.trade.model.TradeStatus;
import com.alipay.demo.trade.model.builder.AlipayTradePrecreateRequestBuilder;
import com.alipay.demo.trade.model.result.AlipayF2FPrecreateResult;
import com.alipay.demo.trade.service.AlipayTradeService;
import com.alipay.demo.trade.service.impl.AlipayTradeServiceImpl;
import com.mrd.frame.domain.AccessConfig;
import com.mrd.frame.domain.Order;
import com.mrd.frame.domain.OrderInteraction;
import com.mrd.frame.domain.message.PayMessage;
import com.mrd.frame.domain.params.PayParams;
import com.mrd.frame.onlinepay.AliPayApi;
import com.mrd.frame.onlinepay.QrCreateBean;
import com.mrd.frame.onlinepay.pay.IPay;
import com.mrd.frame.service.OrderInteractionService;
import com.mrd.frame.service.OrderService;
import com.mrd.weixinpay.util.Constents;
import com.mrd.weixinpay.util.PayCommonUtil;

/**
 * 支付宝支付接口实现
 * 
 * @author han
 */
@Component("alipay")
public class Alipay extends AliPayApi implements IPay {
	private static final Logger logger = Logger.getLogger(Alipay.class);
	@Value("${pay.airpay.timeoutExpress}")
	private String timeoutExpress;//支付超时
	@Value("${pay.airpay.notifyUrl}")
	private String notifyUrl;
	
	@Override
	public Map<String, Object> pay(AccessConfig accessConfig,
			PayParams payParams, Order order, OrderInteraction orderInt,
			PayMessage payMessage, OrderService orderService,
			OrderInteractionService orderInteractionService) {

		Map<String, Object> retMap = new HashMap<String, Object>();
		SortedMap<Object, Object> xmlMap = new TreeMap<Object, Object>();
		
		String newRequest = "NO";// 是否需要从新发起支付
		String retresXML = "";// 支付请求返回的xml
		
		// 将订单信息插入订单表中
		saveOrder(order, orderService,payParams);

		//转换出一个要保存参数map，保存到交互记录的xml或者用于交易
		xmlMap = getPayOrderXmlMap(order, payParams);
		
		// 向第三方的支付请求存入交互记录表中
		saveOrderInteraction(orderInteractionService,orderInt,xmlMap);

		// 发起支付
		JSONObject result = null;
		try {
			result = pay(xmlMap,accessConfig);
		} catch (Exception e) {
			e.printStackTrace();
		}

		// 将支付宝支付返回的信息存入交互表中
		SaveRtnMsg( orderService, payMessage, order , xmlMap , result, newRequest, orderInt,orderInteractionService,retresXML);

		retMap.put("retresXML", retresXML);
		retMap.put("newRequest", newRequest);
		retMap.put("payMessage", payMessage);
		return retMap;
	}

	/**
	 * 保存订单
	 * @author han
	 */
	private void saveOrder(Order order, OrderService orderService,PayParams payParams) {
		order.setOrderId(String.valueOf(System.currentTimeMillis()));
		order.setPayChannel("2");
		order.setStatus("1");
		order.setTradeNo(payParams.getOutTradeNo());
		order.setTimeStart(new Date());
		order.setTotalAmount(Integer.parseInt(payParams.getTotalAmount()));
		order.setTradeType("1");
		order.setUserKey(payParams.getUserKey());
		order.setPayType(trade_type);
		try{
			orderService.insert(order);
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}

	/**
	 * 封装一个保存参数以及支付参数的Map
	 * 将map保存到记录表，同时用于支付
	 * @author han
	 * @return SortedMap<Object, Object> 
	 */
	public SortedMap<Object, Object> getPayOrderXmlMap(Order order, PayParams payParams){
		SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
		packageParams.put("outTradeNo", order.getOrderId());//订单号
		packageParams.put("subject", payParams.getSubject());//订单标题
		packageParams.put("totalAmount", payParams.getTotalAmount());//订单总金额
		packageParams.put("undiscountableAmount", "0");//折扣
		packageParams.put("sellerId", "");//卖家支付宝账号ID
		packageParams.put("body", payParams.getBody());//订单描述
		packageParams.put("operatorId", "test_operator_id");//商户操作员编号
		packageParams.put("storeId", "test_store_id");//商户门店编号
		packageParams.put("timeoutExpress", "120m");//支付超时
		packageParams.put("sign", payParams.getSign());//签名，支付宝没使用到
		String requestXML = PayCommonUtil.getRequestXml(packageParams);
		logger.info("支付宝支付请求发送的消息：" + requestXML);
		System.out.println("支付宝支付请求发送的消息：" + requestXML);
		return packageParams;
	}
	
	/**
	 * 请求存入交互记录表中
	 * @author han
	 */
	private void saveOrderInteraction(OrderInteractionService orderInteractionService,OrderInteraction orderInt,SortedMap<Object, Object> packageParams) {
		String requestXML = PayCommonUtil.getRequestXml(packageParams);
		logger.info("支付宝支付请求发送的消息：" + requestXML);
		System.out.println("支付宝支付请求发送的消息：" + requestXML);
		// 向第三方的支付请求存入交互记录表中
		orderInt.setCreateTime(new Date());
		orderInt.setParameters(requestXML);
		orderInt.setOrderInteractionId(String.valueOf(System.currentTimeMillis()));
		orderInt.setType("A2");
		orderInt.setStatus("0");
		orderInt.setOrderId((String)packageParams.get("outTradeNo"));
		orderInt.setOrderInteractionId(String.valueOf(System.currentTimeMillis()));
		Integer a2 = orderInteractionService.insert(orderInt);
	}

	/**
	 * 发起支付
	 * @Subject 标题
	 * @author han
	 */
	public JSONObject pay(SortedMap<Object, Object> packageParams,AccessConfig accessConfig) throws Exception {
		int total = Integer.parseInt((String)packageParams.get("totalAmount"));
		AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
		model.setSubject((String)packageParams.get("subject"));
		float val  = (float)total/100;
		model.setTotalAmount(String.valueOf(val));
		model.setStoreId("");
		model.setTimeoutExpress(timeoutExpress);
		model.setOutTradeNo((String)packageParams.get("outTradeNo"));
		String resultStr = tradePrecreatePay(model, notifyUrl,accessConfig.getUserKey());
		JSONObject jsonObject = JSONObject.parseObject(resultStr);
		return jsonObject;
	}
	  
	/**
	 * 返回信息存入记录表
	 * @author han
	 */
	private void SaveRtnMsg(OrderService orderService,PayMessage payMessage,Order order,
			SortedMap<Object, Object> xmlMap,JSONObject result,
			String newRequest,OrderInteraction orderInt,
			OrderInteractionService orderInteractionService,String retresXML){
		SortedMap<Object, Object> resultParams = new TreeMap<Object, Object>();
		String retMsg = "";
//		dumpResponse(response);
		JSONObject response = result.getJSONObject("alipay_trade_precreate_response");
		String code = response.getString("code");
		//返回信息
		resultParams.put("body", response.getString("body"));
		resultParams.put("code", response.getString("code"));
		resultParams.put("errorCode", response.getString("error_code"));
		resultParams.put("msg", response.getString("msg"));
		resultParams.put("outTradeNo", response.getString("out_trade_no"));
		resultParams.put("qrCode", response.getString("qr_code"));
		resultParams.put("subCode", response.getString("sub_code"));
		resultParams.put("subMsg", response.getString("sub_msg"));
		orderInt.setParameters(PayCommonUtil.getRequestXml(resultParams));
		
		retresXML = PayCommonUtil.getRequestXml(resultParams);
		
		if(code.equals("10000")){
			orderInt.setStatus("0");
		}else{
			orderInt.setStatus("1");
		}
		orderInt.setCreateTime(new Date());
		orderInt.setOrderInteractionId(String.valueOf(System.currentTimeMillis()));
		orderInt.setType("A3");
		Integer a3 = orderInteractionService.insert(orderInt);
		//插入交易记录结束
		
		if(code.equals("10000")){
			String codeUrl = response.getString("qr_code");
			String nonStr = order.getOrderId();
			String qrAddress = arCreateBean.saveQr(codeUrl, nonStr);
			order.setQrUrl(qrAddress);
			Integer r2 = orderService.updateByPrimaryKeySelective(order);
			payMessage.setCode(Integer.parseInt("1"));
			payMessage.setMessage(Constents.SUCCESMESSAGE);
			payMessage.setOutTradeNo((String)xmlMap.get("outTradeNo"));
			payMessage.setQrUrl(qrAddress);
			payMessage.setResultCode(response.getString("code"));
			payMessage.setReturnCode(response.getString("code"));
			payMessage.setSign((String)xmlMap.get("sign"));//有疑问
			payMessage.setReturnMsg(response.getString("msg"));
			payMessage.setTradeType(trade_type);
		}else{
			if(code.equals("40004")){
				retMsg = "支付失败。";
				newRequest = "YES";
			}else if(code.equals("10003")){
				retMsg = "等待用户付款。";
			}else{
				retMsg = " 未知异常 。";
				newRequest = "YES";
			}
			payMessage.setMessage(retMsg);
			payMessage.setCode(Integer.parseInt("1"));
			payMessage.setOutTradeNo((String)xmlMap.get("outTradeNo"));
			payMessage.setResultCode(response.getString("code"));
			payMessage.setReturnCode(response.getString("code"));
			payMessage.setSign((String)xmlMap.get("sign"));//有疑问
			payMessage.setReturnMsg(response.getString("msg"));
			payMessage.setTradeType(trade_type);
		}
	}
	
}
